#include "../include/mutex.h"
#include <stdexcept>

namespace shiosylar
{

Semaphore::Semaphore(uint32_t count)
{
    if(sem_init(&m_semaphore, 0, count))
        throw std::logic_error("sem_init error");
}

Semaphore::~Semaphore()
{
    sem_destroy(&m_semaphore);
}

void Semaphore::wait()
{
    if(sem_wait(&m_semaphore))
        throw std::logic_error("sem_wait error");
}

void Semaphore::notify()
{
    if(sem_post(&m_semaphore))
        throw std::logic_error("sem_post error");
}

// FiberSemaphore::FiberSemaphore(size_t initial_concurrency)
//     :m_concurrency(initial_concurrency) {
// }

// FiberSemaphore::~FiberSemaphore() {
//     SYLAR_ASSERT(m_waiters.empty());
// }

// bool FiberSemaphore::tryWait() {
//     SYLAR_ASSERT(Scheduler::GetThis());
//     {
//         MutexType::Lock lock(m_mutex);
//         if(m_concurrency > 0u) {
//             --m_concurrency;
//             return true;
//         }
//         return false;
//     }
// }

// void FiberSemaphore::wait() {
//     SYLAR_ASSERT(Scheduler::GetThis());
//     {
//         MutexType::Lock lock(m_mutex);
//         if(m_concurrency > 0u) {
//             --m_concurrency;
//             return;
//         }
//         m_waiters.push_back(std::make_pair(Scheduler::GetThis(), Fiber::GetThis()));
//     }
//     Fiber::YieldToHold();
// }

// void FiberSemaphore::notify() {
//     MutexType::Lock lock(m_mutex);
//     if(!m_waiters.empty()) {
//         auto next = m_waiters.front();
//         m_waiters.pop_front();
//         next.first->schedule(next.second);
//     } else {
//         ++m_concurrency;
//     }
// }

} // namespace shiosylar end
